package com.edushare.common.dao.academics.grades;

import java.util.List;

import com.edushare.common.dao.CourseGradeDAO;
import com.edushare.common.dao.EntityAttribSetDAO;
import com.edushare.common.orm.ORMInterface;
import com.edushare.common.vo.Batches;
import com.edushare.common.vo.CourseGrade;
import com.edushare.common.vo.Enrolments;
import com.edushare.common.vo.Users;

public class SGCalculation {
	private Users user;
	private Batches batch;
	private int semNum;

	public SGCalculation(Users user, Batches batch, int semesterNum) {
		this.user = user;
		this.batch = batch;
		this.semNum = semesterNum;
	}

	public double getSemGradePointAverage(ORMInterface orm) {
		double gradePoints = getSemGradePoints(orm);
		int totalCredits = getCredits();
		if (totalCredits == 0)
			return 0.0;
		return gradePoints / totalCredits;

	}

	public double getSemGradePoints(ORMInterface orm) {
		List<Enrolments> enrolList = user.getEnrolments();
		double gradePoints = 0;
		for (Enrolments e : enrolList) {
			if (e.getBatchLink() == batch && semNum == e.getBatchSemNum()) {
				CourseGrade g = new CourseGradeDAO(orm).getUserCourseGrade(
						user, e.getCourseInstance());
				if (g == null)
					return 0.0;
				int tempCredits = e.getCourseInstance().getInstanceCredits();
				if (g.getEvaluationType() == CourseGrade.EVAL_GRADE
						&& g.getGradeKey().isPass()) {
					gradePoints += (g.getGradeKey().getGradeNumber() * tempCredits);
				} else {
					gradePoints += (g.getMarks() * tempCredits);
				}
			}
		}
		return gradePoints;
	}

	public int getSuccessfulCredits(ORMInterface orm) {
		List<Enrolments> enrolList = user.getEnrolments();
		int credits = 0;
		for (Enrolments e : enrolList) {
			if (e.getBatchLink() == batch && semNum == e.getBatchSemNum()) {
				CourseGrade g = new CourseGradeDAO(orm).getUserCourseGrade(
						user, e.getCourseInstance());
				if (g == null)
					continue;
				int tempCredits = e.getCourseInstance().getInstanceCredits();
				if (g.getEvaluationType() == CourseGrade.EVAL_GRADE
						&& g.getGradeKey().isPass()) {
					credits += tempCredits;
				} else {
					int passMark = new EntityAttribSetDAO(orm)
							.getUnivAttributeInt(batch.getCurricula()
									.getUniversity(), "PASS_MARKS");
					if (g.getMarks() >= passMark) {
						credits += tempCredits;
					}
				}
			}
		}
		return credits;
	}

	public int getFailureCredits(ORMInterface orm) {
		return getCredits() - getSuccessfulCredits(orm);
	}

	public int getCredits() {
		int credits = 0;
		List<Enrolments> enrolList = user.getEnrolments();
		for (Enrolments e : enrolList) {
			if (e.getBatchLink() == batch && e.getBatchSemNum() == semNum) {
				credits += e.getCourseInstance().getInstanceCredits();
			}
		}
		return credits;
	}

	public int getSuccessfulCumulativeCredits(ORMInterface orm) {
		List<Enrolments> enrolList = user.getEnrolments();
		int credits = 0;
		for (Enrolments e : enrolList) {
			if (e.getBatchLink() == batch) {
				CourseGrade g = new CourseGradeDAO(orm).getUserCourseGrade(
						user, e.getCourseInstance());
				if (g == null)
					continue;
				int tempCredits = e.getCourseInstance().getInstanceCredits();
				if (g.getEvaluationType() == CourseGrade.EVAL_GRADE
						&& g.getGradeKey().isPass()) {
					credits += tempCredits;
				} else {
					int passMark = new EntityAttribSetDAO(orm)
							.getUnivAttributeInt(batch.getCurricula()
									.getUniversity(), "PASS_MARKS");
					if (g.getMarks() >= passMark) {
						credits += tempCredits;
					}
				}
			}
		}
		return credits;
	}

	public int getTotalCredits() {
		int credits = 0;
		List<Enrolments> enrolList = user.getEnrolments();
		for (Enrolments e : enrolList) {
			if (e.getBatchLink() == batch) {
				credits += e.getCourseInstance().getInstanceCredits();
			}
		}
		return credits;
	}

	public double getTotalGradePoints(ORMInterface orm) {
		double gradePoints = 0.0;
		List<Enrolments> enrolList = user.getEnrolments();
		for (Enrolments e : enrolList) {
			if (e.getBatchLink() == batch) {
				CourseGrade g = new CourseGradeDAO(orm).getUserCourseGrade(
						user, e.getCourseInstance());
				if (g == null)
					return 0.0;
				int tempCredits = e.getCourseInstance().getInstanceCredits();
				if (g.getEvaluationType() == CourseGrade.EVAL_GRADE
						&& g.getGradeKey().isPass()) {
					gradePoints += (g.getGradeKey().getGradeNumber() * tempCredits);
				} else {
					gradePoints += (g.getMarks() * tempCredits);
				}
			}
		}
		return gradePoints;
	}

	public double getCGPA(ORMInterface orm) {
		if (getTotalCredits() == 0)
			return 0.0;
		return getTotalGradePoints(orm) / getTotalCredits();
	}

}
